﻿/*************************************************************************
 *
 * Copyright (c) 2009-2014 Xuld. All rights reserved.
 * 
 * Project Url: http://work.xuld.net/circus
 * 
 * This source code is part of the Project Circus.
 * 
 * This code is licensed under The Circus License.
 * See the file License.html for the license details.
 * 
 * 
 * You must not remove this notice, or any other, from this software.
 *
 * 
 *************************************************************************/


using System;

namespace Circus.Utility {

    /// <summary>
    /// 提供类型转换的相关方法。
    /// </summary>
    public static class ConvertHelper {

        /// <summary>
        /// 将数字的字符串表示形式转换为它的等效 8 位有符号整数, 失败则返回默认值。
        /// </summary>
        /// <param name="value">要转换的字符串。</param>
        /// <param name="defaultValue">转换失败后返回的默认值。</param>
        /// <returns>返回转换后的整数。</returns>
        public static byte parseByte(string value, byte defaultValue = 0) {
            byte result;
            return byte.TryParse(value, out result) ? result : defaultValue;
        }

        /// <summary>
        /// 将数字的字符串表示形式转换为它的等效 8 位无符号整数, 失败则返回默认值。
        /// </summary>
        /// <param name="value">要转换的字符串。</param>
        /// <param name="defaultValue">转换失败后返回的默认值。</param>
        /// <returns>返回转换后的整数。</returns>
        public static sbyte parseSByte(string value, sbyte defaultValue = 0) {
            sbyte result;
            return sbyte.TryParse(value, out result) ? result : defaultValue;
        }

        /// <summary>
        /// 将数字的字符串表示形式转换为它的等效 16 位无符号整数, 失败则返回默认值。
        /// </summary>
        /// <param name="value">要转换的字符串。</param>
        /// <param name="defaultValue">转换失败后返回的默认值。</param>
        /// <returns>返回转换后的整数。</returns>
        public static ushort parseUShort(string value, ushort defaultValue = 0) {
            ushort result;
            return ushort.TryParse(value, out result) ? result : defaultValue;
        }

        /// <summary>
        /// 将数字的字符串表示形式转换为它的等效 16 位有符号整数, 失败则返回默认值。
        /// </summary>
        /// <param name="value">要转换的字符串。</param>
        /// <param name="defaultValue">转换失败后返回的默认值。</param>
        /// <returns>返回转换后的整数。</returns>
        public static short parseShort(string value, short defaultValue = 0) {
            short result;
            return short.TryParse(value, out result) ? result : defaultValue;
        }

        /// <summary>
        /// 将数字的字符串表示形式转换为它的等效 32 位有符号整数, 失败则返回默认值。
        /// </summary>
        /// <param name="value">要转换的字符串。</param>
        /// <param name="defaultValue">转换失败后返回的默认值。</param>
        /// <returns>返回转换后的整数。</returns>
        public static int parseInt(string value, int defaultValue = 0) {
            int result;
            return int.TryParse(value, out result) ? result : defaultValue;
        }

        /// <summary>
        /// 将数字的字符串表示形式转换为它的等效 32 位无符号整数, 失败则返回默认值。
        /// </summary>
        /// <param name="value">要转换的字符串。</param>
        /// <param name="defaultValue">转换失败后返回的默认值。</param>
        /// <returns>返回转换后的整数。</returns>
        public static uint parseUInt(string value, uint defaultValue = 0) {
            uint result;
            return uint.TryParse(value, out result) ? result : defaultValue;
        }

        /// <summary>
        /// 将数字的字符串表示形式转换为它的等效 64 位有符号整数, 失败则返回默认值。
        /// </summary>
        /// <param name="value">要转换的字符串。</param>
        /// <param name="defaultValue">转换失败后返回的默认值。</param>
        /// <returns>返回转换后的整数。</returns>
        public static long parseLong(string value, long defaultValue = 0) {
            long result;
            return long.TryParse(value, out result) ? result : defaultValue;
        }

        /// <summary>
        /// 将数字的字符串表示形式转换为它的等效 64 位无符号整数, 失败则返回默认值。
        /// </summary>
        /// <param name="value">要转换的字符串。</param>
        /// <param name="defaultValue">转换失败后返回的默认值。</param>
        /// <returns>返回转换后的整数。</returns>
        public static ulong parseULong(string value, ulong defaultValue = 0) {
            ulong result;
            return ulong.TryParse(value, out result) ? result : defaultValue;
        }

        /// <summary>
        /// 将数字的字符串表示形式转换为它的等效 32 位有符号浮点数, 失败则返回默认值。
        /// </summary>
        /// <param name="value">要转换的字符串。</param>
        /// <param name="defaultValue">转换失败后返回的默认值。</param>
        /// <returns>返回转换后的浮点数。</returns>
        public static float parseFloat(string value, float defaultValue = 0) {
            float result;
            return float.TryParse(value, out result) ? result : defaultValue;
        }

        /// <summary>
        /// 将数字的字符串表示形式转换为它的等效 64 位有符号浮点数, 失败则返回默认值。
        /// </summary>
        /// <param name="value">要转换的字符串。</param>
        /// <param name="defaultValue">转换失败后返回的默认值。</param>
        /// <returns>返回转换后的浮点数。</returns>
        public static double parseDouble(string value, double defaultValue = 0) {
            double result;
            return double.TryParse(value, out result) ? result : defaultValue;
        }

        /// <summary>
        /// 将数字的字符串表示形式转换为它的等效十进制数, 失败则返回默认值。
        /// </summary>
        /// <param name="value">要转换的字符串。</param>
        /// <param name="defaultValue">转换失败后返回的默认值。</param>
        /// <returns>返回转换后的整数。</returns>
        public static decimal parseDecimal(string value, decimal defaultValue = 0) {
            decimal result;
            return decimal.TryParse(value, out result) ? result : defaultValue;
        }

        /// <summary>
        /// 将字符串转为布尔值。如果字符串是空、false则返回 false，否则返回 true。
        /// </summary>
        /// <param name="value">要转换的字符串。</param>
        /// <param name="defaultValue">转换失败后返回的默认值。</param>
        /// <returns>返回转换后的整数。</returns>
        public static bool parseBool(string value, bool defaultValue = false) {
            if (String.IsNullOrEmpty(value)) {
                return defaultValue;
            }
            return value != "0" && String.Compare("false", value, true) != 0 && String.Compare("off", value, true) != 0 && String.Compare("no", value, true) != 0;
        }

        /// <summary>  
        /// 将字符串转为 GMT 时间。如果转换失败则返回当前时间。
        /// </summary>  
        /// <param name="value">要转换的字符串。</param>
        /// <returns>返回 GMT 时间。</returns>
        public static DateTime parseDateTime(string value) {
            DateTime result;
            return DateTime.TryParse(value, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AdjustToUniversal, out result) ? result : DateTime.Now;
        }

        /// <summary>  
        /// 将字符串转为 GMT 时间。
        /// </summary>  
        /// <param name="value">要转换的字符串。</param>
        /// <param name="defaultValue">转换失败后返回的默认值。</param>
        /// <returns>返回 GMT 时间。</returns>
        public static DateTime parseDateTime(string value, DateTime defaultValue) {
            DateTime result;
            return DateTime.TryParse(value, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AdjustToUniversal, out result) ? result : defaultValue;
        }

        /// <summary>
        /// 将指定的字符串解析为指定类型的值。
        /// </summary>
        /// <param name="value">要解析的字符串。</param>
        /// <param name="type">要解析的目标类型。</param>
        /// <returns>返回解析后的对象值。转换失败则返回 null。</returns>
        public static object parseObject(string value, Type type) {

            // 常用类型加速解析。
            if (type == typeof(string)) {
                return value;
            }
            if (type == typeof(int)) {
                return parseInt(value);
            }
            if (type == typeof(long)) {
                return parseLong(value);
            }
            if (type == typeof(bool)) {
                return parseBool(value);
            }
            if (type == typeof(DateTime)) {
                return parseDateTime(value);
            }

            // 其它值类型。
            if (type.IsValueType) {
                if (type.IsEnum) {
                    try {
                        return Enum.Parse(type, value, true);
                    } catch {
                        return Activator.CreateInstance(type);
                    }
                }
                if (type == typeof (byte)) {
                    return parseByte(value);
                }
                if (type == typeof (short)) {
                    return parseShort(value);
                }
                if (type == typeof (decimal)) {
                    return parseDecimal(value);
                }
                if (type == typeof (float)) {
                    return parseFloat(value);
                }
                if (type == typeof(double)) {
                    return parseDouble(value);
                }
                if (type == typeof (sbyte)) {
                    return parseSByte(value);
                }
                if (type == typeof (ushort)) {
                    return parseUShort(value);
                }
                if (type == typeof(uint)) {
                    return parseUInt(value);
                }
                if (type == typeof(ulong)) {
                    return parseULong(value);
                }
            }

            // 引用类型采用 JSON 格式化。
            try {
                return Circus.Utility.Json.Json.currentEngine.parse(value, type);
            } catch {
                return null;
            }

        }

        /// <summary>
        /// 将 IP 地址转为长整型。
        /// </summary>
        /// <param name="value">要转换的ip地址 格式127.0.0.1 式。</param>		
        /// <returns>返回转化成整型后的ip地址,格式不对则返回-1 。</returns>			
        public static int ipToNumber(string value) {
            if (value == null) {
                return -1;
            }

            string[] parts = value.Split('.');

            //长度不为4则返回-1
            if (parts.Length != 4) {

                if (value == "::1") {
                    return 127 | (0 << 8) | (0 << 16) | (1 << 24);
                }

                return -1;
            }

            return parseByte(parts[3]) | (parseByte(parts[2]) << 8) | (parseByte(parts[1]) << 16) | (parseByte(parts[0]) << 24);
        }

        /// <summary>
        /// 将长整型转为 IP 地址。
        /// </summary>
        /// <param name="value">输入ip地址的整型格式。</param>		
        /// <returns>转化成ip地址，格式127.0.0.1 。</returns>			
        public static string numberToIp(int value) {
            var parts = new string[4];
            for (int i = 3; i >= 0; i--) {
                parts[i] = (value % 256).ToString();
                value >>= 8;
            }
            return String.Join(".", parts);
        }

    }
}
